//
//  Primer_Protocol_DemoVC.swift
//  APSwift
//
//  Created by jianbo.pei on 2022/5/9.
//

import UIKit

/// 定义一个`eat`协议
protocol eatProtocol {
    func eat()
}

/// 定义一个`sleep`协议
protocol sleepProtocol {
    func sleep()
}

/// 声明一个`Student`结构体，同时遵守`eatProtocol`和`sleepProtocol`两个协议
struct Student : eatProtocol, sleepProtocol {
    func eat() {
        print("student eat")
    }
    
    func sleep() {
        print("student sleep")
    }
}


class Animal {
    var nickName: String?
}

/// `Dog`类，继承自`Animal`类，同时遵守`eatProtocol`和`sleepProtocol`两个协议
class Dog : Animal, eatProtocol, sleepProtocol {
    func eat() {
        print("dog eat")
    }
    
    func sleep() {
        print("dog sleep")
    }
}


protocol foodProtocol {
    /// 表示`foodName`属性是可读可写的
    var foodName: String { get set }
}




class Primer_Protocol_DemoVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        test1()
    }


}


//!!!: test1 begin
protocol FullyNamed {
    var fullName: String { get }
}

struct Person: FullyNamed {
    var fullName: String
}

class Starship: FullyNamed {
    var prefix: String?
    var name: String
    init(name: String, prefix: String? = nil) {
        self.name = name
        self.prefix = prefix
    }
    var fullName: String {
        return (prefix != nil ? prefix! + " " : "") + name
    }
}


extension Primer_Protocol_DemoVC {
    private func test1() {
        let john = Person(fullName: "John Appleseed")
        print("john.fullName is \(john.fullName)")
        
        let ncc1701 = Starship(name: "Enterprise", prefix: "USS")
        print("ncc1701.fullName is \(ncc1701.fullName)")
    }
}

//!!!: test1 end


//!!!: test2 begin
/*
 - 值类型的实例方法里面想修改它的内存的话必须加上`mutating`
 - 只有协议里加上`mutating`，结构体里实现时才能加上`mutating`
 - 类在实现方法时不能加`mutating`
 */
protocol Drawable {
    mutating func draw()
}

class Size: Drawable {
    var width: Int = 0
    func draw() {
        width = 10
    }
}

struct Point: Drawable {
    var x: Int = 0
    mutating func draw() {
        x = 10
    }
}
//!!!: test2 end


//!!!: test3 begin
/*
 - 协议中还可以定义初始化器`init`
 - 非final类实现时必须加上`required`
 - final: 不能有子类
 */

//!!!: test3 end


//!!!: test4 begin
/*
 /// 协议组合

 - 协议组合，可以包含1个类类型（最多1个）
 */

//!!!: test4 end
